#include "../test_type.h"
#include "../../src/ipc/IpcIoServer.h"
#include "../../src/ipc/IpcIoSocket.h"
#include "../../src/log/LogFactory.h"
#include "../../src/thread/SharedPtr.h"
#include <iostream>
#include <memory>
#include <map>
using namespace LibTools;
using namespace std;

DWORD DealAccept(CSockError ec, void* invoker);
DWORD DealRead(char* data, DWORD dwSize, CSockError ec, void* invoker);
DWORD DealWrite(char* data, DWORD dwSize, CSockError ec, void* invoker);

#define BUF_SIZE 1024

static SharedPtr<CIpcIoServer> g_service = new CIpcIoServer(true);
static char g_bufs[3][BUF_SIZE] = { 0 };
static map<SOCKIDEN, char*>  g_mapBufs;
static bool g_run = true;

#ifdef TEST_IPC_SERVER
int main(int argc, char* argv[])
{
#ifdef WIN32
	LibTools::ShareApi::PrintDumpInfo(true);
#else
	LibTools::ShareApi::PrintDumpInfo();
#endif
	LOG_SET_LEVEL(LibTools::LOG_NORMAL);
	LOG_SET_WRITE_CONSOLE(true);
	CSockError ec = g_service->Init("TEST_IPC_SERVER");
	CHECKERROR(ec, "init failed!");
	CIpcIoSocket cliIPC[3];
	for (int i = 0; i < 3; i++)
	{
		cliIPC[i].SetService(g_service->GetIpcServicePtr());
		cliIPC[i].AsyncAccept(&DealAccept, &(cliIPC[i]));
		g_mapBufs[cliIPC[i].GetSocketID()] = g_bufs[i];
	}
	LOG_TOOLS(LOG_NORMAL) << "run ...";
	while (g_run) g_service->Run_One();
	g_service->WaitServerStop();

	return 0;
}
#endif // TEST_IPC_SERVER

DWORD DealAccept(CSockError ec, void* invoker)
{
	CIpcSocket *ipc = (CIpcSocket*)invoker;
	LOG_TOOLS(LOG_NORMAL) << "connect succ?" << (bool)(ec.GetError() == CSockError::SUCC) << ", client id:" << ipc->GetSocketID();
	if (!ec){
		g_service->AsyncRead(*ipc, CStreamIteator(g_mapBufs[ipc->GetSocketID()], g_mapBufs[ipc->GetSocketID()] + BUF_SIZE), &DealRead, invoker);
	}
	else 
	{
		LOG_TOOLS(LOG_NORMAL) << "error:" << ec.GetErrorMsg();
		g_run = false;
	}

	return ec.GetError();
}

DWORD DealRead(char* data, DWORD dwSize, CSockError ec, void* invoker)
{
	CIpcSocket *ipc = (CIpcSocket*)invoker;
	LOG_TOOLS(LOG_NORMAL) << "read succ?" << (bool)(ec.GetError() == CSockError::SUCC) << ", client id:" << ipc->GetSocketID();
	if (!ec) 
	{
		LOG_TOOLS(LOG_NORMAL) << "read size:" << dwSize << ",msg:" << string(g_mapBufs[ipc->GetSocketID()], g_mapBufs[ipc->GetSocketID()] + dwSize);
		g_service->AsyncSend(*ipc, CStreamIteator(g_mapBufs[ipc->GetSocketID()], g_mapBufs[ipc->GetSocketID()] + dwSize), &DealWrite, invoker);
	}
	else 
	{
		LOG_TOOLS(LOG_NORMAL) << "error:" << ec.GetErrorMsg();
		g_run = false;
	}

	return ec.GetError();
}

DWORD DealWrite(char* data, DWORD dwSize, CSockError ec, void* invoker)
{
	CIpcSocket *ipc = (CIpcSocket*)invoker;
	LOG_TOOLS(LOG_NORMAL) << "send succ?" << (bool)(ec.GetError() == CSockError::SUCC) << ", client id:" << ipc->GetSocketID();
	if (!ec){
		g_service->AsyncRead(*ipc, CStreamIteator(g_mapBufs[ipc->GetSocketID()], g_mapBufs[ipc->GetSocketID()] + BUF_SIZE), &DealRead, invoker);
	}
	else 
	{
		LOG_TOOLS(LOG_NORMAL) << "error:" << ec.GetErrorMsg();
		g_run = false;
	}

	return ec.GetError();
}